home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / SCROLLSOURCE / Scroll.c next >
C/C++ Source or Header  |  1987-01-03  |  18KB  |  738 lines

  1. /*********************************************************************
  2.  
  3.     Scroll.c
  4.  
  5.     Programmed by Keith Lambert 1986,87
  6.     Compuserve 75076,34
  7.     GEnie K.Lambert
  8.     
  9.     OR
  10.     
  11.     3433 Marathon Drive
  12.     San Diego, Calif.  92123
  13.     
  14.     Please leave me mail if you have any problems or questions with this
  15.     code.
  16.     
  17.     This file is for the LightspeedC development system. If you are not
  18.     using this system, you will have to make the neccessary adjustments.
  19.     
  20.     This program will display a Modal Dialog box that contains a 
  21.     scrollable list of items similiar to the SFGetFile. However this
  22.     program does not use any list manager routines. 
  23.     
  24.     This program is meant to be an example only, and it might serve as a
  25.     template for your own application.
  26.     There are no general routines to build a dynamic text list for display 
  27.     in the dialog. This is left up to the specific application. This example 
  28.     only uses a    list of 20 strings that are in a global array for its text.
  29.     
  30.     This code contains some examples on using filter procedures and 
  31.     user item procedures for modal dialog boxes.
  32.     
  33. *********************************************************************/
  34.  
  35.  
  36.  
  37. #include "QuickDraw.h"   
  38. #include "MacTypes.h"
  39. #include "FontMgr.h"
  40. #include "WindowMgr.h"
  41. #include "MenuMgr.h"
  42. #include "TextEdit.h"
  43. #include "DialogMgr.h"
  44. #include "EventMgr.h"
  45. #include "DeskMgr.h"
  46. #include "FileMgr.h"
  47. #include "ToolboxUtil.h"
  48. #include "ControlMgr.h"
  49. #include "strings.h"
  50. #include "ctype.h"
  51. #include "types.h"
  52. #include "pascal.h"
  53. #include "Scroll.h"
  54.  
  55. #define            NUMSTRS 20                    /* number of strings in dialog     */
  56. #define            SCROLLDELAY 10000            /* to slow down scrolling a little*/
  57.  
  58.  
  59. /* GLOBAL VARIABLES */
  60.  
  61. EventRecord        myEvent;
  62. DialogPtr        myWindow;                    /*ptr to the dialog window*/
  63. WindowPtr         EvWindow;                    /* Event window*/
  64. MenuHandle        myMenus[4];
  65.  
  66. short                startValue,endValue;        /* scroll bar values                        */
  67. int                 MIN = 0 , MAX ;            /* min and max values for scroll bar*/
  68. int                LinesShow;                    /* number of lines in scroll box*/
  69. int                height;                        /* line height in text edit record*/
  70.  
  71. TEHandle            theText;                        /* Handle to the text edit record */
  72.  
  73.  
  74. /* the text items in the scrolling dialog */
  75. /* normally you would have to build this list dynamically in your application */
  76. /* but since this is just an example program, let keep it simple.                    */
  77.  char                *Strs[] = {
  78.                                     "Airborne\r",
  79.                                     "Archon\r",
  80.                                     "Cyborg\r",
  81.                                     "Gato\r",
  82.                                     "Grid Wars\r",
  83.                                     "Lode Runner\r",
  84.                                     "MacGolf\r",
  85.                                     "Maze Wars+\r",
  86.                                     "Mystery Box\r",
  87.                                     "Orbiter\r",
  88.                                     "Orbquest\r",
  89.                                     "Pinball\r",
  90.                                     "Rogue\r",
  91.                                     "Sargon\r",
  92.                                     "Shanghai\r",
  93.                                     "SkyFox\r",
  94.                                     "Think Ahead+\r",
  95.                                     "Winter Games\r",
  96.                                     "Wizardry\r",
  97.                                     "Zork\r"
  98.                                     } ;                
  99.  
  100.  
  101.  
  102.  
  103. restartProc()
  104. {
  105.     ExitToShell();
  106. }
  107.  
  108. Init()
  109. {
  110.     MaxApplZone();
  111.     MoreMasters();
  112.     MoreMasters();
  113.     MoreMasters();
  114.     InitGraf(&thePort);
  115.     InitFonts();
  116.     FlushEvents( everyEvent, 0 );
  117.     InitWindows();
  118.     InitMenus();
  119.     TEInit();
  120.     InitDialogs(&restartProc);
  121.     InitCursor();
  122.     SetUpMenus();
  123.     
  124.     
  125. }    /* end Init();    */
  126.  
  127.  
  128. main() 
  129. {
  130.     Init();
  131.     
  132.     while (MainEvent()) ;
  133. }
  134.  
  135.  
  136. int MainEvent() 
  137. {
  138.     
  139.     WindowPtr        whichWindow;
  140.     
  141.     SystemTask();
  142.     
  143.     if (GetNextEvent(everyEvent, &myEvent)) 
  144.     {
  145.         
  146.         
  147.         switch (myEvent.what) 
  148.         {
  149.             case mouseDown:
  150.                 switch (FindWindow( myEvent.where, &whichWindow )) 
  151.                 {
  152.                     case inDesk: 
  153.                         SysBeep(10);
  154.                         break;
  155.                     case inGoAway:
  156.                         break;
  157.                     case inMenuBar:
  158.                          DoCommand( MenuSelect(myEvent.where) );
  159.                     case inSysWindow:
  160.                         SystemClick( &myEvent, whichWindow );
  161.                         break;
  162.                     case inDrag:
  163.                         break;
  164.                     case inGrow:
  165.                         break;
  166.                     case inContent:
  167.                         checkClick();
  168.                         break;
  169.                     default: ;
  170.                 } /* end switch FindWindow */
  171.                 break;
  172.             
  173.             case keyDown:
  174.             case autoKey: 
  175.                 if ((myEvent.modifiers & cmdKey))            /* menu equivalent ?*/
  176.                     DoCommand(MenuKey(myEvent.message)); 
  177.                 break;
  178.             case activateEvt:
  179.                 break;
  180.             case updateEvt:                                    /* Someone said window needs refresh*/
  181.                 EvWindow = (WindowPtr)myEvent.message;             /* Which window?*/
  182.                 UpdateWind(EvWindow);                                    /* Do the update*/
  183.                 break;
  184.  
  185.             
  186.             default: 
  187.             break;
  188.         }                     /* end of case myEvent.what */
  189.     }                         /* if */
  190.     
  191.     
  192.     
  193.     return(1);
  194. }
  195.  
  196. SetUpMenus()  
  197. {
  198.     int        i;
  199.     
  200.     myMenus[appleM] =  GetMenu(appleID);
  201.     AddResMenu( myMenus[appleM], 'DRVR' );
  202.     myMenus[fileM] = GetMenu(fileID);
  203.     myMenus[editM] = GetMenu(editID);
  204.     myMenus[dlogM] = GetMenu(DialogID);
  205.     
  206.     for ( (i=appleM); (i<=dlogM); i++ ) InsertMenu(myMenus[i], 0) ;
  207.     DrawMenuBar();
  208.     
  209.     
  210. }
  211.  
  212.  
  213. int DoCommand( mResult )
  214. long mResult;
  215. {
  216.     short        theItem;
  217.     Str255    name;
  218.     GrafPtr     savePort;
  219.     long        size,memAvail;
  220.     Handle    myResHandle,myHandle;
  221.     
  222.      
  223.     theItem = LoWord( mResult );
  224.     switch (HiWord(mResult)) 
  225.     {
  226.         case appleID:              
  227.              if (theItem == 1) 
  228.                  BragAbout();
  229.              else 
  230.              {        /* check memory before opening DA,  */
  231.                    GetItem(myMenus[appleM], theItem, &name);    
  232.                    SetResLoad(FALSE);
  233.                    myResHandle = GetNamedResource('DRVR',&name);
  234.                    size = SizeResource(myResHandle) + 3072;
  235.                    SetResLoad(TRUE);
  236.                    if((memAvail = CompactMem(size)) > size )
  237.                    {
  238.                        GetPort(&savePort);
  239.                          OpenDeskAcc( &name );
  240.                         SetPort(savePort);
  241.                     }
  242.                        else 
  243.                        SysBeep(5);        /* not enough memouy ! */
  244.                
  245.             }
  246.             
  247.               break;
  248.         case fileID: 
  249.             DoFile(theItem);
  250.             break;
  251.         case editID:
  252.             if(SystemEdit(theItem-1)); 
  253.             break;
  254.         case DialogID:
  255.             DoDialogMenu(theItem);
  256.             break;
  257.     }    
  258.     HiliteMenu(0);
  259.     return(1);
  260. }
  261.  
  262. /*============================================================================
  263.  Procedure DoFile():
  264.  Process all File menu selections here.
  265. ============================================================================*/
  266.  DoFile(item)
  267.  int        item;
  268.  {
  269.      switch(item)
  270.      {
  271.             case 1:                                /* QUIT*/
  272.                 ExitToShell();
  273.                  break;
  274.      }                                
  275.     
  276.  }                                    
  277.  
  278. /*============================================================================
  279.  Procedure DoDialogMenu():
  280.  Process all dialog menu selections here.
  281. ============================================================================*/
  282.  
  283. DoDialogMenu(item)
  284. short item;
  285. {
  286.  
  287.     switch(item)
  288.     {
  289.         case 1:
  290.             DoDialog1();
  291.             break;
  292.     
  293.     }
  294.     
  295. }    /* end DoOptMenu()  */
  296.  
  297.  
  298.  
  299. /*============================================================================
  300.  * Procedure BragAbout:
  301.  * Display a dialog box that tells a little about the program.
  302.  *============================================================================*/
  303.  BragAbout()
  304. {
  305.     short          itemHit;
  306.     GrafPtr         savePort;
  307.     Handle        iconHand;
  308.     
  309.  
  310.          GetPort(&savePort);                        /* save the current port*/
  311.         myWindow = GetNewDialog(100,0,-1);
  312.         SetPort(myWindow);
  313.          itemHit = 0;
  314.      
  315.         while(itemHit < 1)                            /* while not in Ok*/
  316.          {
  317.           ModalDialog(0,&itemHit);            /* wait for mouse click*/
  318.          }
  319.         
  320.         DisposDialog(myWindow);
  321.          SetPort(savePort);
  322.         
  323.     
  324. }                                /* END BragAbout*/
  325.  
  326. /*==============================================================================
  327.  * Dobold()
  328.  * this is the user item procedure to make the thick outline around the default
  329.  * button ( assumed to be item 1)
  330.  *=============================================================================*/
  331.  
  332. pascal void Dobold(dlogPtr,item)
  333. DialogPtr                dlogPtr;
  334. unsigned short    item;
  335. {
  336.     unsigned short        itype;
  337.     Handle                ihandle;
  338.     Rect                    irect;
  339.  
  340.         GetDItem(dlogPtr,1,&itype,&ihandle,&irect);    /* get the buttons rect */
  341.         PenSize(3,3);                                            /* make thick lines     */
  342.         InsetRect(&irect,-4,-4);                            /* grow rect a little   */
  343.         FrameRoundRect(&irect,16,16);                        /* frame the button now */
  344.         PenNormal();
  345.     
  346. }
  347.  
  348.     
  349. /*=============================================================================
  350.  * DrawScrollText()
  351.  * this the the user item procedure for the scrolling items display. It will 
  352.  * draw the rectangle around the text and set up text edit record for the 
  353.  * items in the dialog. 
  354.  * for some reason I couldn't get the rectangle of the useritem so I could 
  355.  * draw a rectangle around it, so instead I got the rect of the scrollbar
  356.  * and adjusted that rect to the appropriate size.
  357.  *============================================================================*/
  358.  
  359. pascal void DrawScrollText(dlogPtr,item)
  360. DialogPtr                dlogPtr;  
  361. unsigned short    item;
  362. {
  363.     register int         x;
  364.     unsigned short      itype;
  365.     Handle                ihandle;
  366.     Rect                    irect,theRect,viewRect,destRect;
  367.     
  368.     
  369.     
  370.         GetDItem(dlogPtr,4,&itype,&ihandle,&irect);    /* get the scroll bars rect*/
  371.         
  372.         BlockMove(&irect,&theRect,sizeof(Rect));        /* copy the rect */
  373.         theRect.left -=  120;                            /* adjust left and right sides*/
  374.         theRect.right -= 15;
  375.         
  376.         FrameRect(&theRect);            
  377.         
  378.         BlockMove(&theRect,&viewRect,sizeof(Rect));
  379.         InsetRect(&viewRect,1,1);                            /* shrink viewRect a little*/
  380.         
  381.         BlockMove(&viewRect,&destRect,sizeof(Rect));
  382.         
  383.         
  384.         theText = TENew(&destRect,&viewRect);            /* setup textedit record*/
  385.         
  386.         height = (*theText)->lineHeight;                    /* line height in pixels */
  387.         
  388.         /* calculate how many lines will show in the rectangle */
  389.         LinesShow = (viewRect.bottom-viewRect.top)/height;
  390.         
  391.         /* set the control max to the number of strings - how many will show */
  392.         MAX = (NUMSTRS - LinesShow);
  393.         
  394.                         
  395.         SetCtlMin(ihandle,MIN);                        /* set the control values */
  396.         SetCtlMax(ihandle,MAX);
  397.         SetCtlValue(ihandle,MIN);
  398.         
  399.         
  400.         for(x=0;x<NUMSTRS;x++)                        /* insert the strings into record*/
  401.         {
  402.             TEInsert(Strs[x],strlen(Strs[x]),theText);
  403.             
  404.         }
  405.  
  406.     
  407. }
  408.  
  409.  
  410. /*=============================================================================
  411.  * scrollAction()
  412.  * this is the action procedure that is used whenever the mouse is held down in
  413.  * the scroll bar arrow or page regions. Basically all it does is set the 
  414.  * control value and then call scrolltext. This procedure executes so fast that
  415.  * holding down the mouse in the up or down arrows will scroll by more that one
  416.  * line every time so a small dealy has be inserted at the end to adjust it so
  417.  * it will scroll only one line.
  418.  *============================================================================*/
  419.  
  420. pascal void scrollAction(theControl,partcode)
  421. ControlHandle    theControl;
  422. short                partcode;
  423. {
  424.     register int    x;
  425.     
  426.         startValue = GetCtlValue(theControl);
  427.         
  428.             switch(partcode)
  429.             {
  430.                 case inUpButton:
  431.                     if(startValue > MIN )    /* to avoid rattling scroll box */
  432.                     { 
  433.                         SetCtlValue(theControl, startValue - 1 );
  434.                         ScrollText(theControl);
  435.                     }
  436.                     break;
  437.                     
  438.                 case  inDownButton:
  439.                     if(startValue < MAX )
  440.                     {
  441.                         SetCtlValue(theControl, startValue + 1  );
  442.                         ScrollText(theControl);
  443.                     }
  444.                     break;
  445.                 
  446.                 case  inPageUp:
  447.                     if(startValue > MIN )
  448.                     {
  449.                         SetCtlValue(theControl, startValue - (LinesShow-1));
  450.                         ScrollText(theControl);
  451.                     }
  452.                     break;
  453.                     
  454.                 case  inPageDown:
  455.                     if(startValue < MAX )
  456.                     {
  457.                         SetCtlValue(theControl, startValue + (LinesShow-1));
  458.                         ScrollText(theControl);
  459.                     }
  460.                     break;
  461.             } 
  462.         
  463.         
  464.         endValue = GetCtlValue(theControl);        /* not really used here  */
  465.         
  466.         
  467.         for(x=0;x<SCROLLDELAY;x++);        /* slow down scrolling, too fast otherwise */
  468. }
  469.  
  470.  
  471.  
  472. /*==============================================================================
  473.  * ScrollText()
  474.  * this procedure will scroll the text in the text edit record after the scroll
  475.  * bar has been adjusted/
  476.  *============================================================================*/
  477.  
  478. ScrollText(theControl)
  479. ControlHandle theControl;
  480. {
  481.  
  482.     RgnHandle    updateRgn;
  483.     int            scrollValue,scrollDiff,oldScroll,newScroll,ViewTop,DestTop;
  484.                 
  485.             
  486.  
  487.     
  488.         ViewTop = (*theText)->viewRect.top;
  489.         DestTop = (*theText)->destRect.top;
  490.         
  491.         oldScroll = (ViewTop - DestTop);
  492.         scrollValue = GetCtlValue(theControl);
  493.         
  494.         newScroll = (scrollValue * height);
  495.         scrollDiff = (oldScroll - newScroll);
  496.         
  497.         if (scrollDiff != 0)
  498.             TEScroll(0,scrollDiff,theText);
  499.  
  500.         
  501. }
  502. /*============================================================================
  503.  * scrollFilter()
  504.  * this is the filter proc for the modal dialog. It handles events the way I
  505.  * want them. keyDown events will be checked for the RETURN of ENTER keys and be 
  506.  * treated like a press in the OK button. Pressing the TILDE key will be treated
  507.  * like the CANCEL button. All other key presses are ignored.
  508.  * mouseDown events are checked to see if they are in the SCROLL BAR or the
  509.  * rectangle containg the scrolling text. Other mouse downs are handled by
  510.  * ModalDialog.
  511.  *===========================================================================*/
  512.  
  513. pascal char scrollFilter(dp,event,item)            
  514. DialogPtr                dp;
  515. EventRecord            *event;
  516. unsigned short        *item;
  517. {
  518.     char                 c,result;
  519.     char                choosenText[25];     /* storage space for text selected */
  520.     Rect                irect;
  521.     Point                eventPoint;
  522.     ControlHandle    whichControl;
  523.     Handle            ihandle,TES;
  524.     short                partcode,bogus,finalTicks;
  525.     long                startSel,endSel,length;
  526.     int                DestTop,scrollValue,lineHit,x;
  527.     unsigned short itype;
  528.  
  529.         
  530.     
  531.     result = FALSE;
  532.     
  533.     if(event->what == keyDown)                /* we have a key press */
  534.     {
  535.         
  536.         c = event->message & 0x00FF;        /* what character is it? */
  537.         if(c == 0x0003 || c == 0x000D)   /* return or enter keys */
  538.         {
  539.             GetDItem(dp,1,&itype,&ihandle,&irect);
  540.             HiliteControl(ihandle,1);        /* pretend user clicked in button*/
  541.             Delay(4,finalTicks);                /* keep it on screen a moment */
  542.             result = TRUE;
  543.             *item = 1;                            /*select the default button */
  544.         }
  545.         else
  546.         {
  547.             if(c  == 0x0060 || c == 0x007E  )    /*use tilde key for Cancel button*/
  548.             {    GetDItem(dp,2,&itype,&ihandle,&irect);
  549.                 HiliteControl(ihandle,1);
  550.                 Delay(4,finalTicks);
  551.                 result = TRUE;
  552.                 *item = 2;                        /* treat as the cancel button */
  553.             }
  554.             
  555.         }
  556.     }
  557.         
  558.     else if (event->what == mouseDown)                    /* mouse was clicked */
  559.     {
  560.         eventPoint = event->where;                        /* get the location of click*/
  561.         GlobalToLocal(&eventPoint);                    /* got to make it local */
  562.         
  563.         /* see if the click is inside the scrolling text rectangle */
  564.         if (PtInRect( eventPoint, &(**theText).viewRect ))
  565.         {
  566.             TEActivate(theText);
  567.             
  568.             DestTop = (*theText)->destRect.top;
  569.                         
  570.             lineHit = (eventPoint.v - DestTop) / height;     /* what line is hit ? */
  571.              
  572.             if(lineHit < 0)                                    
  573.                     lineHit = 0;
  574.             if(lineHit > (NUMSTRS -1))
  575.                     lineHit = (NUMSTRS -1);
  576.                     
  577.             
  578.  
  579.             /* now we need to invert the selection that was clicked on*/
  580.             /* get the starting and ending point of the string */
  581.             startSel = (*theText)->lineStarts[lineHit];
  582.             endSel = (*theText)->lineStarts[(lineHit+1)];
  583.  
  584.             TESetSelect(startSel,endSel,theText);    /* set and invert selection */
  585.             
  586.             ZeroScrap();                        /* clear out scrap area                    */
  587.             TECopy(theText);                    /* copy selection to textedit scrap */
  588.             TES = TEScrapHandle();            /* get a handle to text just copied    */
  589.             length = TEGetScrapLen();        /* get length of text copied            */
  590.             
  591.             /* NOTE: the text that we have a handle to is just text. It is not*/
  592.             /* a pascal string or a C string, just text. Therefore we cannot  */
  593.             /* use it as a argument to SetIText() because it expects a pointer*/
  594.             /* to a pascal Str255 type not just a pointer to char. To get around*/
  595.             /* this we will copy this text into our own storage space and then */
  596.             /* add a null marker to the end. Thus making it a C string. Then we*/
  597.             /* call CtoPstr() with the string and then pass it to SetIText.    */
  598.             
  599.             HLock(TES);
  600.     
  601.               strcpy(choosenText,*TES);         /* copy text into out storage            */
  602.            
  603.            *(choosenText + length) = '\0';    /* add a null to mark end of string*/
  604.            
  605.             CtoPstr(choosenText);                /* make it a pascal string         */
  606.             
  607.             GetDItem(dp,7,&itype,&ihandle,&irect);        /* get the handel to item 7*/
  608.         
  609.                                             /* set item 7 to the text that was selected */
  610.             SetIText(ihandle,choosenText);             
  611.             PtoCstr(choosenText);                /* change string back to C format */
  612.            HUnlock(TES);
  613.             result = TRUE;
  614.     
  615.         }                                                /* end if ptinrect */
  616.         else                                            /* see where mouse click was */
  617.         {
  618.         
  619.             partcode = FindControl(eventPoint,dp,&whichControl);
  620.         
  621.             if(partcode == inThumb)
  622.             {
  623.                 startValue = GetCtlValue(whichControl);
  624.                 bogus = TrackControl(whichControl,eventPoint,0);
  625.                 endValue = GetCtlValue(whichControl);
  626.                 ScrollText(whichControl);
  627.                 result = TRUE;
  628.             }
  629.             
  630.             /* only watch events in the scroll bar */
  631.             else if(partcode >= inUpButton)
  632.             {
  633.                     bogus = TrackControl(whichControl,eventPoint,&scrollAction);
  634.                       result = TRUE;
  635.             }
  636.         
  637.         }        
  638.                     
  639.         
  640.     }    /* end else if (event->what == mouseDown) */
  641.     
  642.     return(result);
  643. }
  644.  
  645.  
  646.  
  647.  
  648. /*=============================================================================
  649.  * ProcedureDoDialog1()     
  650.  * this is where all the dialog routines are set up.
  651.  * For this Dialog I will use two user items. One for the bold outline on
  652.  * the default button  and the other for the scrolling text and its rect.
  653.  * I will also be using a filter proc to handle the modal dialog events the 
  654.  * way I want them.
  655.  *===========================================================================*/
  656. DoDialog1()     
  657. {
  658.  short                itemHit,itype,x;
  659.  GrafPtr             savePort;
  660.  Rect                    irect;
  661.  Handle                ihandle;
  662.  char                    flag;
  663.  
  664.    GetPort(&savePort);                                    /* save the current port*/
  665.     myWindow = GetNewDialog(500,0,-1);
  666.  
  667.     /* set up the 2 user items for the dialog */
  668.     SetDItem(myWindow,5,userItem,&DrawScrollText,&irect);    
  669.     SetDItem(myWindow,6,userItem,&Dobold,&irect);        
  670.     
  671.     SetPort(myWindow);                                /* dialog is current port*/
  672.     ShowWindow(myWindow);
  673.          
  674.          flag = TRUE;
  675.          while(flag)
  676.      {    
  677.           ModalDialog(&scrollFilter,&itemHit);        /* use a filter routine*/        
  678.           switch(itemHit)
  679.           {
  680.                     case 1:                                             /* OK*/
  681.                         /* insert ok procedures here */    
  682.                         flag = FALSE;                                /* Done with dialog*/
  683.                           break;
  684.                     case 2:                                                /* CANCEL*/
  685.                         /* insert cancel procedures here */
  686.                         flag = FALSE;
  687.                          break;
  688.                     
  689.           }        /* END itemHit switch*/
  690.      }        /* END while TRUE*/
  691.  
  692.  
  693.        TEDispose(theText);                            /* get rid of text edit */
  694.        DisposDialog(myWindow);                        /* get rid of Dialog */
  695.        SetPort(savePort);                            /* restore old port*/
  696.                    
  697. }                /* END  */
  698.  
  699.  
  700. /*=========================================================================*/
  701.  
  702. UpdateWind(wp)
  703.  
  704. WindowPtr wp;
  705. {
  706.  
  707.     BeginUpdate(wp);                                        
  708.  
  709.     SetPort(wp);                                            
  710.                                                                 
  711.     EndUpdate(wp);                                            
  712. }
  713. /*=========================================================================*/
  714.  
  715.  
  716. /*=========================================================================*/
  717.  
  718. checkClick()
  719. {
  720.  
  721.     SysBeep(1);
  722.     
  723. }    /* end of checkClick */
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.